home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dr. Windows 3
/
dr win3.zip
/
dr win3
/
WINPROGS
/
UPC12BS1.ZIP
/
LIB
/
STRPOOL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-09-20
|
10KB
|
296 lines
/*--------------------------------------------------------------------*/
/* s t r p o o l . c */
/* */
/* String dynamic literal pool management for UUPC/extended */
/* */
/* Copyright (c) 1992 by Kendra Electronic Wonderworks; all */
/* rights reserved except those explicitly granted by the */
/* UUPC/extended license. */
/*--------------------------------------------------------------------*/
/*
* $Id: strpool.c 1.4 1993/09/20 04:38:11 ahd Exp $
*
* $Log: strpool.c $
* Revision 1.4 1993/09/20 04:38:11 ahd
* TCP/IP support from Dave Watt
* 't' protocol support
* OS/2 2.x support
*
* Revision 1.3 1992/12/04 01:00:27 ahd
* Delete allocating pool message; now handled by pools allocated summary
*
* Revision 1.2 1992/12/01 04:37:03 ahd
* Add SpeedOverMemory
*
* Revision 1.1 1992/11/22 20:58:55 ahd
* Initial revision
*
*/
/*--------------------------------------------------------------------*/
/* System include files */
/*--------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
/*--------------------------------------------------------------------*/
/* UUPC/extended include files */
/*--------------------------------------------------------------------*/
#include "lib.h"
/*--------------------------------------------------------------------*/
/* Local structures */
/*--------------------------------------------------------------------*/
typedef struct str_queue {
struct str_queue *next_link;
size_t used;
char pool[BUFSIZ];
} STR_QUEUE;
/*--------------------------------------------------------------------*/
/* Local variables */
/*--------------------------------------------------------------------*/
static STR_QUEUE *anchor = NULL;
static const size_t pool_size = BUFSIZ;
static int pools = 0;
#ifdef _UDEBUG
static int strings = 0;
static int used = 0;
static int duplicates = 0;
static int saved = 0;
/*--------------------------------------------------------------------*/
/* Local prototypes */
/*--------------------------------------------------------------------*/
void dump_pool( void );
#endif
/*--------------------------------------------------------------------*/
/* The problem: UUPC/extended allocates large number of small */
/* (<< 50 characters) string variables off the heap which are */
/* never modified and never deallocated. This means that the */
/* possibly duplicate and relatively large overhead required by */
/* malloc and causes these variables to waste space. */
/* */
/* The solution: We use this routine to maintain our own local */
/* pool of storage for allocating NULL terminated strings out */
/* of a chain of large buffers. This allows us to both reduce */
/* storage overhead by placing the strings end to end, and to */
/* optionally scan the list for duplicates entries. */
/* */
/* The duplicate string search can be questionable on a small */
/* system, because we have to walk the entire list to locate */
/* the duplicate. However, a smaller system is less likely to */
/* have a large dynamic string pool, so we take the hit anyway. */
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* s t r p o o l */
/* */
/* Allocate a string from the string poll */
/*--------------------------------------------------------------------*/
char *strpool( const char *input , const char *file, size_t line)
{
int len = strlen( input );
int best_fit = SHRT_MAX;
char *result;
STR_QUEUE *current = anchor;
STR_QUEUE *last = anchor;
STR_QUEUE *save = NULL;
/*--------------------------------------------------------------------*/
/* Perform best fit search */
/*--------------------------------------------------------------------*/
while(current != NULL )
{
int available;
/*--------------------------------------------------------------------*/
/* Scan current buffer for the string */
/*--------------------------------------------------------------------*/
if ( ! bflag[ F_SPEEDOVERMEMORY ] )
{
char *target = current->pool;
char *bufend = target + current->used;
while( target < bufend )
{
int target_len = strlen( target );
int diff = target_len - len;
if ((diff >= 0 ) && equal( target + diff, input))
{
#ifdef _UDEBUG
duplicates ++;
saved += len + 1;
#endif
return target+diff;
}
target += target_len + 1; /* Step to start of next string */
} /* while( offset < current->used ) */
} /* if */
/*--------------------------------------------------------------------*/
/* No string in this buffer, look for best fit in case we need */
/* to allocate the string from scratch */
/*--------------------------------------------------------------------*/
available = pool_size - current->used;
if (( available < best_fit) && (available > len ))
{
best_fit = available;
save = current;
}
else
last = current; /* Save last buffer in case we
have to chain new buffer in */
current = current->next_link;
} /* while */
/*--------------------------------------------------------------------*/
/* We have no matching string, we have to insert the new string */
/* into our pool */
/*--------------------------------------------------------------------*/
if ( save == NULL ) /* We find a buffer? */
{ /* No --> Allocate a new one */
pools ++;
save = malloc( sizeof *save );
checkptr(save, file, line);
if ( anchor == NULL )
{
#ifdef _UDEBUG
atexit( dump_pool );
#endif
anchor = save;
}
else
last->next_link = save;
save->used = 0;
save->next_link = NULL;
}
/*--------------------------------------------------------------------*/
/* Save the string, update memory available in current pool, */
/* and return to the caller with the new string */
/*--------------------------------------------------------------------*/
result = strcpy( save->pool + save->used, input );
save->used += len + 1;
#ifdef _UDEBUG
strings ++;
used += len + 1;
#endif
return result;
} /* strpool */
/*--------------------------------------------------------------------*/
/* s a f e f r e e */
/* */
/* Insure we are not freeing memory saved for a pool */
/*-----------------------------